package edu.washington.cs.sounddetector.server.api.object;

import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import edu.washington.cs.sounddetector.server.api.APIConsts;

/**
 * <p>
 * A LabeledSound holds a recorded sound and a label for that sound.
 * </p>
 * 
 * <p>
 * The sound is assumed to be linear PCM encoded and any other properties (such as sample rate) will
 * be specified by an appropriate SoundFormat.
 * </p>
 * 
 * @author the.dylan.price@gmail.com
 * 
 */
public class LabeledSound
{

    private String soundClass;
    private byte[] sound;

    public LabeledSound()
    {
    }

    /**
     * Construct a new LabeledSound.
     * 
     * @param soundClass
     *            the class label for this sound used in training a classifier. Use the label
     *            {@link APIConsts#UNKNOWN_SOUND_CLASS} for negative examples.
     * @param sound
     *            a linear PCM encoded sound (any other parameters such as sample rate will be
     *            specified by an appropriate SoundFormat)
     */
    public LabeledSound(String soundClass, byte[] sound)
    {
        Validate.notBlank(soundClass);
        Validate.notNull(sound);

        this.soundClass = soundClass;
        this.sound = sound;
    }

    /**
     * @param soundClass
     *            the soundClass to set
     */
    public void setSoundClass(String soundClass)
    {
        this.soundClass = soundClass;
    }

    /**
     * @param sound
     *            the sound to set
     */
    public void setSound(byte[] sound)
    {
        this.sound = sound;
    }

    /**
     * @return the soundClass
     */
    public String getSoundClass()
    {
        return soundClass;
    }

    /**
     * @return this LabeledSound's sound
     */
    public byte[] getSound()
    {
        return sound;
    }

    @Override
    public String toString()
    {
        return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
                .append("soundClass", soundClass).append("sound", sound).toString();
    }

    @Override
    public int hashCode()
    {
        return new HashCodeBuilder().append(soundClass).append(sound).hashCode();
    }

    @Override
    public boolean equals(Object obj)
    {
        if (!(obj instanceof LabeledSound))
        {
            return false;
        }
        LabeledSound other = (LabeledSound) obj;
        return new EqualsBuilder().append(this.sound, other.sound)
                .append(this.soundClass, other.soundClass).isEquals();
    }
}
